package com.ruoyi.web.controller.cpsp;
/*
    @author neu.xiangwenjuan
    @create 2022/3/26
*/

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.cpsp.domain.*;
import com.ruoyi.cpsp.mapper.EvaluateRecordToEmployeeMapper;
import com.ruoyi.cpsp.service.EmployeeService;
import com.ruoyi.cpsp.service.EvaluateRecordService;
import com.ruoyi.cpsp.service.PerformanceHistoryService;
import com.ruoyi.framework.web.domain.server.Sys;
import com.ruoyi.system.service.ISysDeptService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.text.DecimalFormat;
import java.util.*;

@CrossOrigin
@RestController
@RequestMapping("/cpsp/data")
public class PerformanceHistoryController {

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private PerformanceHistoryService performanceHistoryService;

    @Autowired
    private ISysDeptService iSysDeptService;

    @Autowired
    private EvaluateRecordToEmployeeMapper evaluateRecordToEmployeeMapper;

    @Autowired
    private EvaluateRecordService evaluateRecordService;

    /**
     *
     * @param pageNum
     * @param pageSize
     * @param lastSort  目前金额/月 上个季度的绩效值，0-升序，1-降序，2-不排序 默认值为2
     * @param currentSort  当前季度绩效 本月目前的绩效值，0-升序，1-降序，2-不排序 默认值为2
     * @return
     */
    // 添加两个参数，给上一个月绩效和这个月目前的绩效值排序
    @ApiOperation("获得员工当前季度的绩效数据，没有排序")
    @RequestMapping(value = "/getPerformanceInfo", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getPerformanceInfo(@RequestParam(defaultValue = "1")Integer pageNum,
                                          @RequestParam(defaultValue = "10")Integer pageSize,
                                          @RequestParam(defaultValue = "2")Integer lastSort,
                                          @RequestParam(defaultValue = "2")Integer currentSort) {

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        String role = sysUser.getRoles().get(0).getRoleKey();
        SysDept dept = iSysDeptService.selectDeptById(sysUser.getDeptId());
        String departmentId = dept.getDepartmentId();

        PageInfo<EmployeeEntity> source = new PageInfo<>();
        // 得到该角色能查看的员工数据

        List<EmployeeEntity> employees = new ArrayList<>();
        if (role.equals("admin") || role.equals("leader") || role.equals("supervision") || role.equals("sysadmin")) {
            source = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
                employeeService.selectAll();
            });
            employees = new ArrayList<>(source.getList());
        }else if (role.equals("department")){
            source = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
                employeeService.selectEmployeesByDepartment(departmentId);
            });
            employees = new ArrayList<>(source.getList());
        }
        PageInfo<PerformanceInfo> target = new PageInfo<>();
        BeanUtils.copyProperties(source, target);

        List<PerformanceInfo> list = performanceInfoUnit(employees);
        target.setList(sortList(list, list.size(), lastSort, currentSort));
        return AjaxResult.success(target);
    }

    //@PreAuthorize("@ss.hasPermi('performance:illegal:calculate')")
    @ApiOperation("手动将上一季度的绩效值汇总，并将本季度绩效值保存至数据库表")
    @RequestMapping(value = "/insertCurrentPerformanceInfo", method = RequestMethod.POST)
    @ResponseBody
    private AjaxResult updatePerformanceQuarter() {
        // 每个季度结束时，需要更新下一季度绩效的初值，其中生产岗累加100，辅助岗累加50。
        // 得到当前年份和季度。
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        int quarter = getSeason(new Date());
        int lastYear; int lastQuarter;
        if (performanceHistoryService.selectPerformanceValue(year, quarter).size() > 0){
            return AjaxResult.success(year + "年度" + quarter +"季度绩效初值已经计算，请不要重复计算！");
        }
        // 上季度的绩效的初始值。
        List<PerformanceHistory> histories = new ArrayList<>();
        List<EvaluateRecordCurrentQuarter> sumProp = new ArrayList<>();
        if (quarter > 1) {
            lastYear = year; lastQuarter = quarter - 1;
            histories = performanceHistoryService.selectPerformanceValue(year, quarter - 1);
            sumProp = evaluateRecordService.getMaxProp(year,quarter - 1);
        }else {
            lastQuarter = 4; lastYear = year - 1;
            histories = performanceHistoryService.selectPerformanceValue(year - 1,4);
            sumProp = evaluateRecordService.getMaxProp(year - 1,4);
        }
        // 先计算上季度绩效的实际值。
        for (EvaluateRecordCurrentQuarter sum : sumProp) {
            for (PerformanceHistory history:histories) {
                if (sum.getEmployeeIdCard().equals(history.getEmployeeIdCard())) {
                    if (sum.getMaxProp() > 1){
                        history.setPerformanceValue(0.0);
                    }else {
                        history.setPerformanceValue(history.getPerformanceValue() * (1 - sum.getMaxProp()));
                    }
                }
            }
        }
        // 不得更新上一季度的历史绩效信息嘛。
        for (PerformanceHistory history :histories) {
            performanceHistoryService.updateByPrimaryKeySelective(history);
        }
        // 需要先更新本季度的绩效值。
        for (PerformanceHistory history : histories) {
            if (employeeService.getIsDirectProducer(history.getEmployeeIdCard()) != null && employeeService.getIsDirectProducer(history.getEmployeeIdCard())) {
                if (history.getPerformanceValue() <= 900) {
                    history.setPerformanceValue(history.getPerformanceValue() + 100);
                }else {
                    history.setPerformanceValue(1000.0);
                }
            }else {
                if (history.getPerformanceValue() <= 450) {
                    history.setPerformanceValue(history.getPerformanceValue() + 50);
                }else {
                    history.setPerformanceValue(500.0);
                }

            }
            history.setYear(year);
            history.setQuarter(quarter);
            history.setId(null);
            performanceHistoryService.insert(history);
        }

        return AjaxResult.success(lastYear + "年"+ lastQuarter + "季度绩效值计算完成，"+ year +"年度"+ quarter+"季度尚未结束，目前只显示绩效初值，请于下季度初进行计算。");
    }

    /**
     *
     * @param pageNum
     * @param pageSize
     * @param department 部门id
     * @param teamGroup 班组id
     * @param employeeInfo name或idCard
     * @param lastSort  目前金额/月 上个季度的绩效值，0-升序，1-降序，2-不排序 默认值为2
     * @param currentSort  当前季度绩效 本月目前的绩效值，0-升序，1-降序，2-不排序 默认值为2
     * @return
     */
    @ApiOperation("筛选绩效数据")
    @RequestMapping(value = "/getPerformanceInfoSelect", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getPerformanceInfoSelect(@RequestParam(defaultValue = "1")Integer pageNum,
                                                @RequestParam(defaultValue = "10")Integer pageSize,
                                                @RequestParam(required = false) String department,
                                                @RequestParam(required = false) Integer teamGroup,
                                                @RequestParam(required = false) String employeeInfo,
                                                @RequestParam(defaultValue = "2")Integer lastSort,
                                                @RequestParam(defaultValue = "2")Integer currentSort) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        String role = sysUser.getRoles().get(0).getRoleKey();
        SysDept dept = iSysDeptService.selectDeptById(sysUser.getDeptId());
        String departmentId = dept.getDepartmentId();

        PageInfo<EmployeeEntity> source = new PageInfo<>();
        // 得到该角色能查看的员工数据

        String departId = department == null ?  "" : department;
        Integer teamId = teamGroup == null ? 0 : teamGroup;
        String employeeIn = employeeInfo == null ? "" : employeeInfo;

        List<EmployeeEntity> employees = new ArrayList<>();
        if (role.equals("admin") || role.equals("leader") || role.equals("supervision") || role.equals("sysadmin")) {
            source = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
                employeeService.selectSelective(departId, teamId, employeeIn);
            });
            employees = new ArrayList<>(source.getList());
        }else if (role.equals("department")){
            source = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
                employeeService.selectSelective(departmentId, teamId, employeeIn);
            });
            employees = new ArrayList<>(source.getList());
        }
        PageInfo<PerformanceInfo> target = new PageInfo<>();
        BeanUtils.copyProperties(source, target);

        List<PerformanceInfo> list = performanceInfoUnit(employees);
        target.setList(sortList(list, list.size(), lastSort, currentSort));
        return AjaxResult.success(target);
    }

    @ApiOperation("筛选绩效数据")
    @RequestMapping(value = "/getAllPerformanceInfoSelect", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getAllPerformanceInfoSelect(@RequestParam(required = false) String department,
                                                @RequestParam(required = false) Integer teamGroup,
                                                @RequestParam(required = false) String employeeInfo,
                                                @RequestParam(defaultValue = "2")Integer lastSort,
                                                @RequestParam(defaultValue = "2")Integer currentSort) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        String role = sysUser.getRoles().get(0).getRoleKey();
        SysDept dept = iSysDeptService.selectDeptById(sysUser.getDeptId());
        String departmentId = dept.getDepartmentId();
        // 得到该角色能查看的员工数据

        String departId = department == null ?  "" : department;
        Integer teamId = teamGroup == null ? 0 : teamGroup;
        String employeeIn = employeeInfo == null ? "" : employeeInfo;

        List<EmployeeEntity> employees = new ArrayList<>();
        if (role.equals("admin") || role.equals("leader") || role.equals("supervision") || role.equals("sysadmin")) {
            employees = employeeService.selectSelective(departId, teamId, employeeIn);

        }else if (role.equals("department")){
            employees = employeeService.selectSelective(departmentId, teamId, employeeIn);
        }

        List<PerformanceInfo> lists = performanceInfoUnit(employees);
        List<PerformanceInfo> list = sortList(lists, lists.size(), lastSort, currentSort);
        return AjaxResult.success(list);
    }

    @ApiOperation("获得员工当前季度的绩效数据")
    @RequestMapping(value = "/getPerformanceInfoSort", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getPerformanceInfoSort() {

        List<EmployeeEntity> employees = employeeService.selectAll();
        System.out.println(employees.size());
        List<PerformanceInfo> list = performanceInfoUnit(employees);

        // 对绩效按照currentProp进行排序。
        List<PerformanceInfo> ajaxResult = new ArrayList<>();
        // currentSort为3,lastSort任意。
        ajaxResult = sortList(list, list.size(), 2, 3);
        return AjaxResult.success(ajaxResult);
    }

    @ApiOperation("首页上半部分——返回每个部门上个季度的总绩效值")
    @RequestMapping(value = "/getPerformanceByDept", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getPerformanceByDept() {
        // 得到当前日期，从而获得年份和季度。
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        int quarter = getSeason(new Date());
        quarter = quarter > 1 ? quarter - 1 : 4;
        year = quarter == 4 ? year - 1 : year;

        // 得到的数据
        List<PerformanceHistoryDept> list = performanceHistoryService.selPerformanceByDept();
        // 对数据排序
        for (int i = 0; i < list.size(); i ++) {
            for (int j = 0; j < list.size() - i - 1; j ++) {
                if (list.get(j).getSumValue() < list.get(j + 1).getSumValue()) {
                    PerformanceHistoryDept temp = list.get(j);
                    list.set(j, list.get(j + 1));
                    list.set(j + 1, temp);
                }
            }
        }
        return AjaxResult.success(list);
    }

    @ApiOperation("首页下半部分——返回根据绩效值排序的员工信息列表。")
    @RequestMapping(value = "/getPerformanceByValue", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getPerformanceByValue() {
        // 得到当前日期，从而获得年份和季度。
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int quarter = getSeason(new Date());

        // 先得到上一个季度绩效值排序有哪几种
        quarter = quarter > 1 ? quarter - 1 : 4;
        year = quarter == 4 ? year - 1 : year;
        List<PerformanceHistory> perValueOrder = performanceHistoryService.selectValueByOrder();
        // 对perValueOrder排序
        Collections.reverse(perValueOrder);

        // perValueOrder.performanceValue得到绩效值，perValueOrder.valueCount得到对应的员工数量
        return AjaxResult.success(perValueOrder);
    }

    /**
     *
     * @param perValue 前端传入需要找哪个绩效值对应的员工列表。
     * @return
     */
    @ApiOperation("首页下半部分——获得绩效值为x的员工列表")
    @RequestMapping(value = "/getEmployeeByValue", method = RequestMethod.POST)
    @ResponseBody
    private AjaxResult getEmployeeByValue(@RequestParam Double perValue) {
        List<EmployeeEntity> list = new ArrayList<>();
        if (perValue == null) return AjaxResult.success(list);
        list = employeeService.selectEmployeeByValue(perValue);
        for (EmployeeEntity employees:list) {
            employees.setAge(tranCardToAge(employees.getIdCard()));
        }
        return AjaxResult.success(list);
    }


    private List<PerformanceInfo> performanceInfoUnit(List<EmployeeEntity> employees) {
        // 得到当前日期，从而获得年份和季度。
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        int quarter = getSeason(new Date());

        // 根据年份和季度数，得到当前季度的初始绩效和上一季度的结束绩效。
        List<PerformanceHistory> currentPerformance = performanceHistoryService.selectPerformanceValue(year, quarter);
        System.out.println("***************************" + currentPerformance.size());
        List<PerformanceHistory> performanceHistories = new ArrayList<>();
        if (quarter > 1) {
            performanceHistories = performanceHistoryService.selectPerformanceValue(year, quarter - 1);
        }else {
            performanceHistories = performanceHistoryService.selectPerformanceValue(year - 1,4);
        }

        // 得到在当前季度每个员工因为违规所扣除的绩效比例的总和。
        List<EvaluateRecordCurrentQuarter> sumProp = evaluateRecordService.getMaxProp(year,quarter);

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        String role = sysUser.getRoles().get(0).getRoleKey();
        SysDept dept = iSysDeptService.selectDeptById(sysUser.getDeptId());
        String departmentId = dept.getDepartmentId();

        List<PerformanceInfo> list = new ArrayList<>();

        DecimalFormat df = new DecimalFormat("######0.00");

        for (EmployeeEntity employee:employees) {
            PerformanceInfo performanceInfo = new PerformanceInfo();
            performanceInfo.setDepartment(employee.getDepartment().getDepartmentName());
            performanceInfo.setJobNumber(employee.getJobNumber());
            if (employee.getTeamGroup() != null) {
                performanceInfo.setTeamGroup(employee.getTeamGroup().getTeamGroupName());
            }else {
                performanceInfo.setTeamGroup("");
            }
            performanceInfo.setName(employee.getName());
            performanceInfo.setPosition(employee.getPositionType());
            boolean flag = false;
            for (PerformanceHistory current:currentPerformance) {
                if (employee.getIdCard().equals(current.getEmployeeIdCard())) {
                    for (EvaluateRecordCurrentQuarter sum:sumProp) {
                        if (sum.getEmployeeIdCard().equals(employee.getIdCard())) {
                            flag = true;
                            if (sum.getMaxProp() >= 1) {
                                performanceInfo.setCurrentProp(0.0);
                                performanceInfo.setProp(1);
                            }else {
                                performanceInfo.setCurrentProp(Double.valueOf(df.format(current.getPerformanceValue()*(1 - sum.getMaxProp()))));
                                performanceInfo.setProp(1-sum.getMaxProp());
                            }
                            break;
                        }
                    }
                    if (!flag) {
                        performanceInfo.setCurrentProp(current.getPerformanceValue());
                        performanceInfo.setProp(0);
                    }

                }
            }
            for (PerformanceHistory history:performanceHistories) {
                if (employee.getIdCard().equals(history.getEmployeeIdCard())) {
                    performanceInfo.setCurrentMoney(history.getPerformanceValue());
                }
            }
            list.add(performanceInfo);
        }
        return list;
    }

    /**
     * 工具类：排序类，对绩效信息进行排序。升序
     */
    private List<PerformanceInfo> sortList(List<PerformanceInfo> list, int size, Integer lastSort, Integer currentSort) {
        if (lastSort == 2 && currentSort == 2) {
            return list;
        }
        if (currentSort == 3) {
            List<PerformanceInfo> result = new ArrayList<PerformanceInfo>();
            for (int i = 0;i < 3; i ++) {
                for (int j = 0; j < size - i - 1; j ++) {
                    if (list.get(j).getCurrentProp() > list.get(j + 1).getCurrentProp()) {
                        PerformanceInfo temp = new PerformanceInfo();
                        temp = list.get(j + 1);
                        list.set(j + 1, list.get(j));
                        list.set(j, temp);
                    }
                }
            }
            for (int i = size - 1; i >= size - 3; i--) {
                result.add(list.get(i));
            }
            return result;
        }
        // 对当前季度绩效升序排序
        if (currentSort == 0) {
            for (int i = 0;i < size - 1; i ++) {
                for (int j = 0; j < size - i - 1; j ++) {
                    if (list.get(j).getCurrentProp() > list.get(j + 1).getCurrentProp()) {
                        PerformanceInfo temp = new PerformanceInfo();
                        temp = list.get(j + 1);
                        list.set(j + 1, list.get(j));
                        list.set(j, temp);
                    }
                }
            }
            // 对目前金额/月不做排序
            if (lastSort == 2) {
                return list;
            }else if (lastSort == 0) { // 对目前金额/月升序
                for (int i = 0;i < size - 1; i ++) {
                    for (int j = 0; j < size - i - 1; j ++) {
                        if (list.get(j).getCurrentProp() < list.get(j+1).getCurrentProp() &&list.get(j).getCurrentMoney() > list.get(j + 1).getCurrentMoney()) {
                            PerformanceInfo temp = new PerformanceInfo();
                            temp = list.get(j + 1);
                            list.set(j + 1, list.get(j));
                            list.set(j, temp);
                        }
                    }
                }
                return list;
            }else {
                for (int i = 0;i < size - 1; i ++) {
                    for (int j = 0; j < size - i - 1; j ++) {
                        if (list.get(j).getCurrentMoney() < list.get(j + 1).getCurrentMoney()) {
                            PerformanceInfo temp = new PerformanceInfo();
                            temp = list.get(j + 1);
                            list.set(j + 1, list.get(j));
                            list.set(j, temp);
                        }
                    }
                }
                return list;
            }
        }else if (currentSort == 1) { // 当前季度绩效降序
            for (int i = 0;i < size - 1; i ++) {
                for (int j = 0; j < size - i - 1; j ++) {
                    if (list.get(j).getCurrentProp() < list.get(j + 1).getCurrentProp()) {
                        PerformanceInfo temp = new PerformanceInfo();
                        temp = list.get(j + 1);
                        list.set(j + 1, list.get(j));
                        list.set(j, temp);
                    }
                }
            }
            if (lastSort == 2) {
                System.out.println("enter");
                return list;
            }else if (lastSort == 0) {
                for (int i = 0;i < size - 1; i ++) {
                    for (int j = 0; j < size - i - 1; j ++) {
                        if (list.get(j).getCurrentMoney() > list.get(j + 1).getCurrentMoney()) {
                            PerformanceInfo temp = new PerformanceInfo();
                            temp = list.get(j + 1);
                            list.set(j + 1, list.get(j));
                            list.set(j, temp);
                        }
                    }
                }
                return list;
            }else {
                for (int i = 0;i < size - 1; i ++) {
                    for (int j = 0; j < size - i - 1; j ++) {
                        if (list.get(j).getCurrentMoney() < list.get(j + 1).getCurrentMoney()) {
                            PerformanceInfo temp = new PerformanceInfo();
                            temp = list.get(j + 1);
                            list.set(j + 1, list.get(j));
                            list.set(j, temp);
                        }
                    }
                }
                return list;
            }
        }else if (currentSort == 2){
            if (lastSort == 0) {
                for (int i = 0;i < size - 1; i ++) {
                    for (int j = 0; j < size - i - 1; j ++) {
                        if (list.get(j).getCurrentMoney() > list.get(j + 1).getCurrentMoney()) {
                            PerformanceInfo temp = new PerformanceInfo();
                            temp = list.get(j + 1);
                            list.set(j + 1, list.get(j));
                            list.set(j, temp);
                        }
                    }
                }
                return list;
            }else {
                for (int i = 0;i < size  - 1; i ++) {
                    for (int j = 0; j < size - i - 1; j ++) {
                        if (list.get(j).getCurrentMoney() < list.get(j + 1).getCurrentMoney()) {
                            PerformanceInfo temp = new PerformanceInfo();
                            temp = list.get(j + 1);
                            list.set(j + 1, list.get(j));
                            list.set(j, temp);
                        }
                    }
                }
                return list;
            }
        }
        return list;
    }

    public int getSeason(Date date) {
        int season = 0;
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }
        return season;
    }

    private int tranCardToAge(String idCard) {
        int age = 0;
        Calendar cal = Calendar.getInstance();
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH)+1;
        int dayNow = cal.get(Calendar.DATE);

        int year = Integer.valueOf(idCard.substring(6, 10));
        int month = Integer.valueOf(idCard.substring(10,12));
        int day = Integer.valueOf(idCard.substring(12,14));

        if ((month < monthNow) || (month == monthNow && day<= dayNow) ){
            age = yearNow - year;
        }else {
            age = yearNow - year-1;
        }
        return age;
    }

}
